/*
 * Copyright 2011 Katsunori Koyanagi
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package sweezy.swf.io
{
	import flash.utils.ByteArray;
	import flash.utils.Endian;

	internal class IOBase
	{

		internal var _bitBuffer:uint;

		internal var _bitCursor:uint;

		internal var _bytes:ByteArray;

		internal var _bytesStack:Array;

		internal var _positionStack:Array;

		public function IOBase(bytes:ByteArray)
		{
			bytes.endian = Endian.LITTLE_ENDIAN;
			bytes.position = 0;
			_bytes = bytes;

			_bytesStack = [];
			_positionStack = [];

			_bitBuffer = 0;
			_bitCursor = 0;
		}

		public function get eof():Boolean
		{
			return _bytes.position >= _bytes.length;
		}

		public function getBytes():ByteArray
		{
			return _bytes;
		}

		public function get length():uint
		{
			return _bytes.length
		}

		public function popBytes():ByteArray
		{
			if (_bytesStack.length === 0)
			{
				return null;
			}

			var current:ByteArray = _bytes;
			_bytes = _bytesStack.pop();
			return current;
		}

		public function popPosition(positionUpdate:Boolean):int
		{
			if (_positionStack.length === 0)
			{
				return 0;
			}

			var pos:uint = _positionStack.pop();
			var diff:int = _bytes.position - pos;
			if (positionUpdate)
			{
				_bytes.position = pos;
			}

			return diff;
		}

		public function get position():uint
		{
			return _bytes.position;
		}

		public function set position(value:uint):void
		{
			_bitCursor = 0;
			_bytes.position = value;
		}

		public function pushBytes(bytes:ByteArray):void
		{
			_bitCursor = 0;
			_bytesStack.push(_bytes);
			_bytes = bytes;
		}

		public function pushPosition():void
		{
			_positionStack.push(_bytes.position);
		}

		public function resetCursor():void
		{
			_bitCursor = 0;
		}

		public function skip(length:int):void
		{
			_bitCursor = 0;
			_bytes.position += length;
		}
	}
}
